/*
 * cdt.c
 */

/// realize interfaces
#include "cdt.h"

/// require interfaces
#include "SEGGER_RTT.h"

#define	CDT_DATA_BUFFER_SIZE	64
#define	CDT_TEXT_BUFFER_SIZE	250

typedef struct
{
	uint8_t dataBuffer[CDT_DATA_BUFFER_SIZE];
	uint8_t dataLength;
	uint8_t textBuffer[CDT_TEXT_BUFFER_SIZE+8];
	uint8_t textLength;
}
Cdt_Data_T;

Cdt_Data_T	Cdt_Data;

static void Cdt_SendX(void);

void Cdt_Init(void)
{
}

void Cdt_Task1ms25(void)
{
	Cdt_SendX();
}

void Cdt_Start(void)
{
	Cdt_Data.dataLength = 0;
}

void Cdt_WriteByte(uint8_t data)
{
	if(Cdt_Data.dataLength<CDT_DATA_BUFFER_SIZE)
	{
		Cdt_Data.dataBuffer[Cdt_Data.dataLength] = data;
		Cdt_Data.dataLength++;
	}
}

void Cdt_WriteWord(uint16_t data)
{
	/// high byte
	if(Cdt_Data.dataLength<CDT_DATA_BUFFER_SIZE)
	{
		Cdt_Data.dataBuffer[Cdt_Data.dataLength] = (uint8_t)(data>>8);
		Cdt_Data.dataLength++;
	}
	/// low byte
	if(Cdt_Data.dataLength<CDT_DATA_BUFFER_SIZE)
	{
		Cdt_Data.dataBuffer[Cdt_Data.dataLength] = (uint8_t)(data);
		Cdt_Data.dataLength++;
	}
}

void Cdt_StartX(void)
{
	Cdt_Data.textLength = 0;
	/// start header
	Cdt_Data.textBuffer[Cdt_Data.textLength++] = 'C';
	Cdt_Data.textBuffer[Cdt_Data.textLength++] = 'D';
	Cdt_Data.textBuffer[Cdt_Data.textLength++] = 'T';
	Cdt_Data.textBuffer[Cdt_Data.textLength++] = ':';
}

static uint8_t Cdt_IntToChar(uint8_t n)
{
	n &= 0x0F;
	return (n<10)? '0'+n: 'A'+n-10;
}

void Cdt_WriteByteX(uint8_t data)
{
	/// high part
	if(Cdt_Data.textLength<CDT_TEXT_BUFFER_SIZE) Cdt_Data.textBuffer[Cdt_Data.textLength++] = Cdt_IntToChar(data>>4);
	/// low part
	if(Cdt_Data.textLength<CDT_TEXT_BUFFER_SIZE) Cdt_Data.textBuffer[Cdt_Data.textLength++] = Cdt_IntToChar(data);
	/// separator
	if(Cdt_Data.textLength<CDT_TEXT_BUFFER_SIZE) Cdt_Data.textBuffer[Cdt_Data.textLength++] = ',';
}

void Cdt_WriteWordX(uint16_t data)
{
	/// first 4 bits
	if(Cdt_Data.textLength<CDT_TEXT_BUFFER_SIZE) Cdt_Data.textBuffer[Cdt_Data.textLength++] = Cdt_IntToChar(data>>12);
	/// second 4 bits
	if(Cdt_Data.textLength<CDT_TEXT_BUFFER_SIZE) Cdt_Data.textBuffer[Cdt_Data.textLength++] = Cdt_IntToChar(data>>8);
	/// third 4 bits
	if(Cdt_Data.textLength<CDT_TEXT_BUFFER_SIZE) Cdt_Data.textBuffer[Cdt_Data.textLength++] = Cdt_IntToChar(data>>4);
	/// last 4 bits
	if(Cdt_Data.textLength<CDT_TEXT_BUFFER_SIZE) Cdt_Data.textBuffer[Cdt_Data.textLength++] = Cdt_IntToChar(data);
	/// separator
	if(Cdt_Data.textLength<CDT_TEXT_BUFFER_SIZE) Cdt_Data.textBuffer[Cdt_Data.textLength++] = ',';
}

static void Cdt_SendX(void)
{
	if(Cdt_Data.textLength)
	{
		/// end tail
		Cdt_Data.textBuffer[Cdt_Data.textLength++] = 'E';
		Cdt_Data.textBuffer[Cdt_Data.textLength++] = 'N';
		Cdt_Data.textBuffer[Cdt_Data.textLength++] = 'D';
		Cdt_Data.textBuffer[Cdt_Data.textLength++] = '.';
		Cdt_Data.textBuffer[Cdt_Data.textLength++] = '\r';
		Cdt_Data.textBuffer[Cdt_Data.textLength++] = '\n';
		/// write to rtt
		SEGGER_RTT_WriteNoLock(0, Cdt_Data.textBuffer, Cdt_Data.textLength);
		/// for next
		Cdt_Data.textLength = 0;
	}
}

